package com.shanzmoo.merchant.manage.api.manager;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.shanzmoo.base.bean.PageRespBase;
import com.shanzmoo.base.bean.SResponse;
import com.shanzmoo.core.domain.vo.SysRoleSelectVO;
import com.shanzmoo.db.module.msys.entity.MSysRoleEntity;
import com.shanzmoo.db.module.msys.entity.MSysRoleMenuEntity;
import com.shanzmoo.db.module.msys.service.*;
import com.shanzmoo.db.module.psys.domain.dto.RoleSaveDTO;
import com.shanzmoo.db.module.psys.domain.dto.RoleUpdateDTO;
import com.shanzmoo.db.module.psys.domain.query.RoleQuery;
import com.shanzmoo.core.domain.vo.SysRolePageVO;
import com.shanzmoo.merchant.manage.api.config.UserComponent;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 角色管理
 *
 * @author： Gzhao 2021/3/28
 */
@Component
@RequiredArgsConstructor
public class SysRoleManager {

    private final IMSysRoleService roleService;
    private final UserComponent userComponent;
    private final IMSysRoleMenuService roleMenuService;

    /**
     * 新增角色
     *
     * @author Gzhao 2021/4/1
     * @param
     */
    @Transactional(rollbackFor = Exception.class)
    public void add(RoleSaveDTO saveDto) {
        MSysRoleEntity roleEntity = saveDto.convertM();

        List<MSysRoleEntity> checkList = roleService.lambdaQuery()
                .eq(MSysRoleEntity::getDeleted, false)
                .eq(MSysRoleEntity::getRoleName, roleEntity.getRoleName())
                .list();

        Assert.isTrue(CollUtil.isEmpty(checkList), "角色名已存在");

        roleEntity.setCreateUser(userComponent.getUserId());
        roleService.save(roleEntity);

        List<MSysRoleMenuEntity> roleMenuList = new ArrayList<>();
        saveDto.getMenuIds().forEach(
                menuId -> {
                    roleMenuList.add(RoleSaveDTO.convertRoleMenuM(roleEntity.getId(), menuId));
                }
        );

        roleMenuService.saveBatch(roleMenuList);
    }

    public SResponse<PageRespBase<SysRolePageVO>> getPageList(RoleQuery queryDto) {
        IPage<MSysRoleEntity> page = roleService.getPageList(queryDto);

        // 查询角色有哪些菜单权限
        List<MSysRoleEntity> list = page.getRecords();
        List<SysRolePageVO> result = new ArrayList<>(list.size());

        if (CollUtil.isNotEmpty(list)) {
            List<Integer> roleIds = list.stream().map(MSysRoleEntity::getId).collect(Collectors.toList());
            List<MSysRoleMenuEntity> roleMenuAllList = roleMenuService.lambdaQuery()
                    .in(MSysRoleMenuEntity::getRoleId, roleIds)
                    .list();
            if (CollUtil.isNotEmpty(roleIds)) {
                result = list.stream()
                        .map(SysRolePageVO::createByM)
                        .collect(Collectors.toList());

                result.forEach(role->{
                    List<Integer> menuIds = roleMenuAllList.stream()
                            .filter(roleMenu -> roleMenu.getRoleId().equals(role.getId()))
                            .map(MSysRoleMenuEntity::getMenuId)
                            .collect(Collectors.toList());
                    role.setMenuIds(menuIds);
                });
            }
        }

        PageRespBase<SysRolePageVO> re = PageRespBase.create(page, result);
        return SResponse.ok(re);
    }

    @Transactional(rollbackFor = Exception.class)
    public void edit(RoleUpdateDTO updateDto) {
        MSysRoleEntity roleEntity = updateDto.convertM();

        List<MSysRoleEntity> checkList = roleService.lambdaQuery()
                .eq(MSysRoleEntity::getDeleted, false)
                .eq(MSysRoleEntity::getRoleName, roleEntity.getRoleName())
                .ne(MSysRoleEntity::getId, roleEntity.getId())
                .list();

        Assert.isTrue(CollUtil.isEmpty(checkList), "角色名已存在");

        roleEntity.setUpdateUser(userComponent.getUserId());
        roleService.updateById(roleEntity);

        // 删除原有角色权限菜单
        roleMenuService.deletedByRoleId(roleEntity.getId());

        List<MSysRoleMenuEntity> roleMenuList = new ArrayList<>();
        updateDto.getMenuIds().forEach(
                menuId -> {
                    roleMenuList.add(RoleSaveDTO.convertRoleMenuM(roleEntity.getId(), menuId));
                }
        );
        roleMenuService.saveBatch(roleMenuList);
    }

    @Transactional(rollbackFor = Exception.class)
    public void deleteById(Integer id) {
        roleService.removeById(id);
        roleMenuService.deletedByRoleId(id);
    }

    public List<SysRoleSelectVO> getSelectList() {
        List<MSysRoleEntity> entityList = roleService.lambdaQuery()
                .eq(MSysRoleEntity::getDeleted, false)
                .list();
        return entityList.stream().map(SysRoleSelectVO::create).collect(Collectors.toList());
    }
}
